`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:
// Design Name:
// Module Name: Cordic_Module
// Project Name:
// Target Devices:
// Tool Versions:
// Description: ****
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////

module Cordic_Module(
    input                       i_clk           ,
    input                       i_rst           ,

    input  signed [31:0]        i_z             ,
    input  signed [31:0]        i_x             ,
    input  signed [31:0]        i_y             ,
    input                       i_valid         ,
    input         [1:0]         mode            ,
    output signed [31:0]        o_z             ,
    output signed [31:0]        o_x             ,
    output signed [31:0]        o_y             ,
    output                      o_ready         ,
    output                      o_result_valid    
);

reg                             ro_ready        ;
reg  signed [31:0]              ro_z            ;
reg  signed [31:0]              ro_x            ;
reg  signed [31:0]              ro_y            ;
reg                             ro_result_valid ;
reg  signed [31:0]              r_xi            ;
reg  signed [31:0]              r_yi            ;
reg  signed [31:0]              r_zi            ;
reg         [15:0]              r_count         ;
reg                             r_active        ;

wire                            w_active        ;
wire signed [31:0]              w_xi_1          ;
wire signed [31:0]              w_yi_1          ;
wire signed [31:0]              w_zi_1          ;

assign w_active       = i_valid & o_ready       ;//激活信号
assign o_ready        = ro_ready                ;
assign o_result_valid = ro_result_valid         ;

assign o_z            = ro_z                    ;
assign o_x            = ro_x                    ;
assign o_y            = ro_y                    ;

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ro_ready <= 'd1;
    else if(w_active)
        ro_ready <= 'd0;
    else if(r_count == 16 - 1)//状态信息
        ro_ready <= 'd1;
    else 
        ro_ready <= ro_ready;
end 

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_active <= 'd0;
    else 
        r_active <= w_active;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_count <= 'd0;
    else if(r_count == 16 - 1)
        r_count <= 'd0;
    else if(r_active | r_count)//迭代计数
        r_count <= r_count + 1;
    else
        r_count <= r_count;
end 

Cordic_XYZ Cordic_XYZ_u0(
    .i_xi           (r_xi       ),
    .i_yi           (r_yi       ),
    .i_zi           (r_zi       ),
    .mode           (mode       ),
    .i_count        (r_count    ),

    .o_xi_1         (w_xi_1     ),
    .o_yi_1         (w_yi_1     ),
    .o_zi_1         (w_zi_1     )
);

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) begin
        r_xi <= 0;
        r_yi <= 0;
        r_zi <= 0;
    end else if(w_active) begin//输入数据
        r_xi <= i_x;
        r_yi <= i_y;  
        r_zi <= i_z;
    end else if(r_active | r_count) begin//迭代数据
        r_xi <= w_xi_1;
        r_yi <= w_yi_1;
        r_zi <= w_zi_1;
    end else begin
        r_xi <= r_xi;
        r_yi <= r_yi;
        r_zi <= r_zi;
    end
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) begin
        ro_z            <= 'd0    ;
        ro_x            <= 'd0    ;
        ro_y            <= 'd0    ;
        ro_result_valid <= 'd0    ;
    end else if(r_count == 16 - 1) begin//输出数据
        ro_z            <= w_zi_1 ;
        ro_x            <= w_xi_1 ;
        ro_y            <= w_yi_1 ;
        ro_result_valid <= 'd1    ;
    end else begin
        ro_z            <= ro_z   ;
        ro_x            <= ro_x   ;
        ro_y            <= ro_y   ;        
        ro_result_valid <= 'd0    ;
    end
end


endmodule
